package middleware

import (
	"admin-nexus-backend/internal/service"
	"admin-nexus-backend/pkg/response"
	"strings"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// DataPermissionMiddleware 数据权限中间件配置
type DataPermissionMiddleware struct {
	DataPermissionService *service.DataPermissionService
}

// NewDataPermissionMiddleware 创建数据权限中间件
func NewDataPermissionMiddleware(dataPermissionService *service.DataPermissionService) *DataPermissionMiddleware {
	return &DataPermissionMiddleware{
		DataPermissionService: dataPermissionService,
	}
}

// DataPermission 数据权限中间件
func (m *DataPermissionMiddleware) DataPermission() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 从上下文获取用户ID（假设已在认证中间件中设置）
		userID, exists := c.Get("userId") // 注意：auth.go 中设置的是 "userId"
		if !exists {
			response.Unauthorized(c, "未授权的访问")
			c.Abort()
			return
		}

		// 获取用户数据权限信息
		permission, err := m.DataPermissionService.GetUserDataPermission(userID.(uint))
		if err != nil {
			response.InternalServerError(c, "获取数据权限失败")
			c.Abort()
			return
		}

		// 根据请求路径确定模型类型
		modelType := m.getModelTypeFromPath(c.Request.URL.Path)

		// 将数据权限信息和服务实例存储到上下文中
		c.Set("dataPermission", permission)
		c.Set("modelType", modelType)
		c.Set("dataPermissionService", m.DataPermissionService)

		c.Next()
	}
}

// 获取模型类型
func (m *DataPermissionMiddleware) getModelTypeFromPath(path string) string {
	path = strings.TrimPrefix(path, "/api/")
	parts := strings.Split(path, "/")

	if len(parts) >= 2 {
		switch strings.ToLower(parts[1]) {
		case "user":
			return "user"
		case "organization":
			return "organization"
		default:
			// 假设其他API路径对应业务模型
			return "business"
		}
	}

	return "business"
}

// GetDataScopeCondition 获取数据权限条件的辅助函数
func GetDataScopeCondition(c *gin.Context) func(db interface{}) interface{} {
	permission, exists := c.Get("dataPermission")
	if !exists {
		return func(db interface{}) interface{} {
			return db
		}
	}

	modelType, exists := c.Get("modelType")
	if !exists {
		modelType = "business"
	}

	// 从全局获取DataPermissionService实例
	// 注意：这里假设在初始化时已经将服务实例存储在全局变量或上下文中
	// 实际实现可能需要根据项目结构调整
	dataPermissionService, exists := c.Get("dataPermissionService")
	if !exists {
		return func(db interface{}) interface{} {
			return db
		}
	}

	// 构建数据权限条件
	condition := dataPermissionService.(*service.DataPermissionService).BuildDataScopeCondition(
		permission.(*service.UserDataPermission),
		modelType.(string),
	)

	return func(db interface{}) interface{} {
		return condition(db.(*gorm.DB))
	}
}
